//using System;
//using System.IO;
//using System.Runtime.Serialization;
//using System.Runtime.Serialization.Formatters;
//using System.Runtime.Serialization.Formatters.Binary;
//using System.Runtime.Serialization.Formatters.Soap;
//using System.IO.Compression;
//using System.Collections;
//using System.Collections.Generic;
//using System.Text;
//using DCRF.Common.Primitive;
//using DCRF.Common.Interface;
//using DCRF.Common.Support;
//using DCRF.Common.Definition;
//using DCRF.Common.Connection;

//namespace DCRF.Common.Collection
//{
//    /// <summary>
//    /// Stores properties of a class in a form of a list of {Key,Type,Value,IsReadOnly}
//    /// Supports Pre/Post event for read/write of properties. Events are read from the container (blockWeb or block if present)
//    /// </summary>
//    public class PropertyCollection
//    {
//        private Dictionary<string, object> properties = new Dictionary<string, object>();

//        private IBlockWeb container = null;

//        private IBlock containerBlock = null;

//        /// <summary>
//        /// </summary>
//        public PropertyCollection(IBlockWeb cont, IBlock contB)
//        {
//            container = cont;
//            containerBlock = contB;
//        }

//        private Guid containerBlockId
//        {
//            get
//            {
//                if (containerBlock == null) return Guid.Empty;
//                return containerBlock.Id;
//            }
//        }

//        private ConnectorCollection containerConnectors
//        {
//            get
//            {
//                if (containerBlock != null) return containerBlock.Connectors;

//                return container.GlobalConnectors;
//            }
//        }

//        /// <summary>
//        /// returns property item with zero tag
//        /// Tag is something like index number for a property, for example key="Column", tag = column index
//        /// </summary>
//        /// <param name="key"></param>
//        /// <returns></returns>
//        public object this[string key]
//        {
//            get
//            {
//                //PropertyKey pKey = new PropertyKey(key, tag);

//                if (containerConnectors.Contains(EventCode.ReadingProperty))
//                {
//                    object externalValue = null;
//                    bool abortAndUseExternal = false;

//                    containerConnectors[EventCode.ReadingProperty].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref externalValue), new ValueTypeHolder<bool>(ref abortAndUseExternal));

//                    if (abortAndUseExternal)
//                    {
//                        return externalValue;
//                    }
//                }

//                if (containerConnectors.Contains(EventCode.ReadingProperty+"."+key))
//                {
//                    object externalValue = null;
//                    bool abortAndUseExternal = false;

//                    containerConnectors[EventCode.ReadingProperty + "." + key].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref externalValue), new ValueTypeHolder<bool>(ref abortAndUseExternal));

//                    if (abortAndUseExternal)
//                    {
//                        return externalValue;
//                    }
//                }

//                object resultValue = null;

//                if (properties.ContainsKey(key) == false)
//                {
//                    resultValue = container.GlobalProperties[key];
//                }
//                else
//                {
//                    //read internal properties
//                    resultValue = properties[key];

//                    if (resultValue == null)
//                    {
//                        throw new Exception("Collection does not contain property with key:" + key);
//                    }
//                }

//                if (containerConnectors.Contains(EventCode.PropertyRead))
//                {
//                    //here external code can modify result
//                    containerConnectors[EventCode.PropertyRead].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref resultValue));
//                }

//                if (containerConnectors.Contains(EventCode.PropertyRead+"."+key))
//                {
//                    //here external code can modify result
//                    containerConnectors[EventCode.PropertyRead + "." + key].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref resultValue));
//                }

//                return resultValue;
//            }
//            set
//            {
//                object newValue = value;

//                if (containerConnectors.Contains(EventCode.UpdatingProperty))
//                {
//                    bool cancelOperation = false;

//                    containerConnectors[EventCode.UpdatingProperty].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref newValue), new ValueTypeHolder<bool>(ref cancelOperation));

//                    if (cancelOperation)
//                    {
//                        //external handler has stated us to cancel update action
//                        return;

//                        //if external handler wants to modify value, it can do this
//                        //by using ref newValue passed to it
//                    }
//                }

//                if (containerConnectors.Contains(EventCode.UpdatingProperty+"."+key))
//                {
//                    bool cancelOperation = false;

//                    containerConnectors[EventCode.UpdatingProperty + "." + key].Raise(containerBlockId, key, new ValueTypeHolder<object>(ref newValue), new ValueTypeHolder<bool>(ref cancelOperation));

//                    if (cancelOperation)
//                    {
//                        //external handler has stated us to cancel update action
//                        return;

//                        //if external handler wants to modify value, it can do this
//                        //by using ref newValue passed to it
//                    }
//                }

//                //check if this key exists already
//                if (!properties.ContainsKey(key))
//                {
//                    //do not add a new property
//                    //only AddProperty method can do this

//                    if (container.GlobalProperties.Contains(key))
//                    {
//                        container.GlobalProperties[key] = value;
//                    }
//                    else
//                    {
//                        throw new Exception("Cannot assign value to a property which does not exist.");
//                    }
//                }
//                else
//                {
//                    properties[key] = value;
//                }

//                if (containerConnectors.Contains(EventCode.PropertyUpdated))
//                {
//                    containerConnectors[EventCode.PropertyUpdated].Raise(containerBlockId, key, value);
//                }

//                if (containerConnectors.Contains(EventCode.PropertyUpdated+"."+key))
//                {
//                    containerConnectors[EventCode.PropertyUpdated + "." + key].Raise(containerBlockId, key, value);
//                }
//            }
//        }

//        public bool Contains(string key)
//        {
//            return properties.ContainsKey(key);
//        }

//        /// <summary>
//        /// Adds a read-write property with no special type checking and no initial value with default tag
//        /// </summary>
//        /// <param name="key"></param>
//        public void Add(string key)
//        {
//            Add(key, null);
//        }
        
//        /// <summary>
//        /// Key,Tag are used as a unique identifier of the property
//        /// Type, readOnly and initialValue are used as data descriptors
//        /// </summary>
//        /// <param name="key"></param>
//        /// <param name="tag"></param>
//        /// <param name="type"></param>
//        /// <param name="rOnly"></param>
//        /// <param name="initialValue"></param>
//        public void Add(string key, object initialValue)
//        {
//            properties.Add(key, initialValue);
//        }

//        public void Delete(string key)
//        {
//            properties.Remove(key);
//        }


//        public string Export()
//        {
//            MemoryStream ms = new MemoryStream();
//            BinaryFormatter bf = new BinaryFormatter();

//            bf.Serialize(ms, properties);

//            string result = Encoding.ASCII.GetString(ms.ToArray());

//            return result;
//        }

//        public void Import(string data)
//        {
//            MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(data));

//            BinaryFormatter bf = new BinaryFormatter();

//            properties = bf.Deserialize(ms) as Dictionary<string, object>;
//        }
//    }
//}
